package org.example.lottery_system.service.impl;

import cn.hutool.crypto.digest.DigestUtil;
import org.example.lottery_system.common.errorcode.ServiceErrorCodeConstants;
import org.example.lottery_system.common.exception.ServiceException;
import org.example.lottery_system.common.utils.JWTUtil;
import org.example.lottery_system.common.utils.RegexUtil;
import org.example.lottery_system.controller.param.ShortMessageLoginParam;
import org.example.lottery_system.controller.param.UserLoginParam;
import org.example.lottery_system.controller.param.UserPasswordLoginParam;
import org.example.lottery_system.controller.param.UserRegisrerParam;
import org.example.lottery_system.dao.dataobject.Encrypt;
import org.example.lottery_system.dao.dataobject.UserDO;
import org.example.lottery_system.dao.mapper.UserMapper;
import org.example.lottery_system.service.UserService;
import org.example.lottery_system.service.VerificationCodeService;
import org.example.lottery_system.service.dto.UserDTO;
import org.example.lottery_system.service.dto.UserLoginDTO;
import org.example.lottery_system.service.dto.UserRegisterDTO;
import org.example.lottery_system.service.enums.UserIdentityEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    VerificationCodeService verificationCodeService;
    @Autowired
    UserMapper userMapper;
    @Override
    public UserRegisterDTO register(UserRegisrerParam param) {
        //校验注册信息
checkRegisterInfo(param);
        //加密私密数据
        UserDO userDO = new UserDO();
        userDO.setUserName(param.getName());
        userDO.setEmail(param.getMail());
        userDO.setPhoneNumber(new Encrypt(param.getPhoneNumber()));
        userDO.setIdentity(param.getIdentity());
        if(StringUtils.hasText(param.getPassword())){
            userDO.setId(DigestUtil.sha1Hex(param.getPassword()));
        }
        //保存数据
        userMapper.insert(userDO);
        //构造返回
        UserRegisterDTO userRegisterDTO  = new UserRegisterDTO();
        userRegisterDTO.setUserId(12L);
        return userRegisterDTO;
    }

    @Override
    public UserLoginDTO login(UserLoginParam param) {
        UserLoginDTO userLoginDTO;
        //类型转换,进来的有手机号登录和验证码登录
        if (param instanceof UserPasswordLoginParam loginParam){
userLoginDTO = loginByUserPassword(loginParam);
        } else if (param instanceof ShortMessageLoginParam loginParm) {
userLoginDTO = loginByShortMessage(loginParm);
        }else {
            throw new ServiceException(ServiceErrorCodeConstants.LOGIN_INFO_NOT_EXIST);
        }
        return null;
    }

    @Override
    public List<UserDTO> findUserInfo(UserIdentityEnum identity) {
String identityString = null == identity? null : identity.name();
//查表
        List<UserDO> userDOList =null ;
        userMapper.selectUserListByIdentity(identityString);
        List<UserDTO> userDTOList = userDOList.stream().
                map(userDO -> {
          UserDTO userDTO = new UserDTO();
          userDTO.setUserName(userDO.getUserName());
          userDTO.setEmail(userDO.getEmail());
          userDTO.setIdentity(UserIdentityEnum.forName(userDO.getIdentity()));
          userDTO.setUserId(userDO.getId());
          userDTO.setPhoneNumber(userDO.getPhoneNumber().getValue());
          return userDTO;
        }).collect(Collectors.toList());
        return userDTOList;
    }

    /**
     * 验证码登录
     * @param loginParm
     * @return
     */
    private UserLoginDTO loginByShortMessage(ShortMessageLoginParam loginParm) {
if(!RegexUtil.checkMobile(loginParm.getLoginMobile())){
    throw new ServiceException(ServiceErrorCodeConstants.PHONE_ERROR);
}
UserDO userDO = userMapper.selectByPhoneNumber(new Encrypt(loginParm.getLoginMobile()));
if (null == userDO){
    throw new ServiceException(ServiceErrorCodeConstants.USER_INFO_IS_EMPTY);
}
else if(StringUtils.hasText(loginParm.getMandatoryIdentity())){
    throw new ServiceException(ServiceErrorCodeConstants.IDENTITY_ERROR);
}
        //校验验证码
      String code =  verificationCodeService.getVerificationCode(loginParm.getLoginMobile());
if (loginParm.getVerificationCode().equals(code)){
throw new ServiceException(ServiceErrorCodeConstants.VERIFICATION_CODE_ERROR);
}
        Map<String,Object> claim = new HashMap<>() ;
        claim.put("id",userDO.getId());
        claim.put("identity",userDO.getIdentity());
        String token = JWTUtil.genJwt(claim);
        UserLoginDTO userLoginDTO = new UserLoginDTO();
        userLoginDTO.setToken(token);
        userLoginDTO.setIdentity(UserIdentityEnum.forName(userDO.getIdentity()));
        return userLoginDTO;
    }

    /**
     * 手机号或邮箱登录
     * @param loginParam
     * @return
     */
    private UserLoginDTO loginByUserPassword(UserPasswordLoginParam loginParam) {
        UserDO userDO = null;
        //判断手机号还是邮箱登录
        if (RegexUtil.checkMail(loginParam.getLoginName())){
            //邮箱登录
            userDO = userMapper.selectByMail(loginParam.getLoginName());
        }else if(RegexUtil.checkMobile(loginParam.getLoginName())){
            //手机号码登录
            userDO = userMapper.selectByPhoneNumber(new Encrypt(loginParam.getLoginName()));
        }
        else {
            throw new ServiceException(ServiceErrorCodeConstants.LOGIN_NOT_EXIST);
        }
if(null == userDO){
    throw new ServiceException(ServiceErrorCodeConstants.USER_INFO_IS_EMPTY);
}
else if(StringUtils.hasText(loginParam.getMandatoryIdentity())){
    throw new ServiceException(ServiceErrorCodeConstants.IDENTITY_ERROR);
} else if (!DigestUtil.sha256(loginParam.getPassword())
        .equals(userDO.getId())) {
    //校验密码不通过
    throw new ServiceException(ServiceErrorCodeConstants.PASSORD_ERROR);
}
Map<String,Object> claim = new HashMap<>() ;
claim.put("id",userDO.getId());
claim.put("identity",userDO.getIdentity());
String token = JWTUtil.genJwt(claim);
        UserLoginDTO userLoginDTO = new UserLoginDTO();
        userLoginDTO.setToken(token);
        userLoginDTO.setIdentity(UserIdentityEnum.forName(userDO.getIdentity()));
        return userLoginDTO;
    }



    private void checkRegisterInfo(UserRegisrerParam param){
        if (param == null){
            throw new ServiceException(ServiceErrorCodeConstants.REGISTER_IS_EMPPTY);
        }
//校验邮箱格式
        if (!RegexUtil.checkMail(param.getMail())){
            throw new ServiceException(ServiceErrorCodeConstants.MAIL_ERROR);
        }
        //校验手机号模式
        if (!RegexUtil.checkMobile(param.getPhoneNumber())){
            throw new ServiceException(ServiceErrorCodeConstants.PHONE_ERROR);
        }
        //校验身份信息
        if (null == UserIdentityEnum.forName(param.getIdentity())){
            throw new ServiceException(ServiceErrorCodeConstants.IDENTITY_ERROR);
        }
        //校验管理员密码必填
        if(param.getIdentity().equalsIgnoreCase(UserIdentityEnum.ADMIN.name()) &&
        !StringUtils.hasText(param.getPassword())){
            throw new ServiceException(ServiceErrorCodeConstants.PASSORD_IS_EMPPTY);
        }
        //密码校验,至少6位数
        if(StringUtils.hasText(param.getPassword()) && !RegexUtil.checkPassword(param.getPassword())){
            throw new ServiceException(ServiceErrorCodeConstants.PASSORD_ERROR);
        }
        //校验邮箱是否被使用
        if (checkMailUsed(param.getMail())){
            throw new ServiceException(ServiceErrorCodeConstants.MAIL_USED);
        }
        //校验手机号是否被使用
if (checkPhoneNumberUser(param.getPhoneNumber())){
    throw new ServiceException(ServiceErrorCodeConstants.PHONE_NUMBER_UESD);
}
    }
public boolean checkPhoneNumberUser(String phoneNumber){
        int count = userMapper.countByPhone(new Encrypt(phoneNumber));
        return count>0;
}
    private boolean checkMailUsed(String mail) {
int count = userMapper.countByMail(mail);
return count>0;
    }
}
